#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
处理近3个学期课表，生成课程列表和教师授课列表
"""

import os
import pandas as pd
from collections import defaultdict

# 文件路径设置
DOC_DIR = "c:\\Users\\admin\\Desktop\\wl-1\\doc"
OUTPUT_DIR = "c:\\Users\\admin\\Desktop\\wl-1\\output"

# 确保输出目录存在
if not os.path.exists(OUTPUT_DIR):
    os.makedirs(OUTPUT_DIR)

# 获取所有课表文件
def get_schedule_files():
    """获取所有课表文件路径"""
    files = []
    for filename in os.listdir(DOC_DIR):
        if filename.endswith('.xls') and '课表' in filename:
            files.append(os.path.join(DOC_DIR, filename))
    return files

# 读取Excel文件数据
def read_excel_data(file_path):
    """读取Excel文件并返回数据"""
    try:
        # 使用pandas读取Excel文件
        df = pd.read_excel(file_path)
        print(f"成功读取文件: {os.path.basename(file_path)}, 数据形状: {df.shape}")
        return df
    except Exception as e:
        print(f"读取文件 {os.path.basename(file_path)} 出错: {str(e)}")
        return None

# 提取课程信息
def extract_course_info(df, course_set):
    """从DataFrame中提取课程信息"""
    if df is None:
        return
    
    # 打印列名以便调试
    print("\n数据列名:")
    print(df.columns.tolist())
    
    # 打印前10行数据以了解格式
    print("\n前10行数据:")
    print(df.head(10))
    
    # 提取课程信息
    processed_rows = 0
    all_teachers = set()  # 用于收集所有找到的教师
    
    # 导入re模块用于正则表达式
    import re
    
    # 遍历所有单元格寻找课程信息
    for index, row in df.iterrows():
        # 遍历每一行的所有单元格
        for col_idx, cell in enumerate(row):
            if pd.notna(cell):
                cell_str = str(cell).strip()
                
                # 跳过空字符串
                if not cell_str:
                    continue
                
                print(f"处理单元格: {cell_str}")
                
                # 增加额外的模式匹配，捕获更多可能的教师信息
                # 尝试直接查找类似 "教师：教师姓名" 或 "老师：教师姓名" 的模式
                teacher_match = re.search(r'[教师老师]：([\u4e00-\u9fa5]+)', cell_str)
                if teacher_match:
                    teacher_name = teacher_match.group(1)
                    # 尝试提取课程名称
                    course_name = cell_str.split(teacher_match.group(0))[0].strip()
                    print(f"  提取到新模式 - 课程: {course_name}, 教师: {teacher_name}")
                    course_set.add((course_name, teacher_name, "24软件1班"))
                    all_teachers.add(teacher_name)
                    processed_rows += 1
                    continue
                
                # 处理实践课程和其他课程格式
                if any(keyword in cell_str for keyword in ['课程：', '★', '☆']):
                    course_info = cell_str
                    
                    # 提取教师姓名 - 查找类似 "★教师姓名" 或 "☆教师姓名" 的模式
                    teacher_match = re.search(r'[★☆]([\u4e00-\u9fa5]+)', course_info)
                    if teacher_match:
                        teacher_name = teacher_match.group(1)
                        # 提取课程名称
                        course_name = re.split(r'[★☆]', course_info)[0].strip()
                        if course_name.startswith('实践课程：'):
                            course_name = course_name[5:]
                        elif course_name.startswith('其他课程：'):
                            course_name = course_name[5:]
                        
                        print(f"  提取到 - 课程: {course_name}, 教师: {teacher_name}")
                        course_set.add((course_name, teacher_name, "24软件1班"))
                        all_teachers.add(teacher_name)
                        processed_rows += 1
                    
                    # 也处理类似 "教师姓名(共N周)" 的模式
                    else:
                        teacher_match = re.search(r'([\u4e00-\u9fa5]+)\(共\d+周\)', course_info)
                        if teacher_match:
                            teacher_name = teacher_match.group(1)
                            # 提取课程名称
                            course_name = course_info.split(teacher_name)[0].strip()
                            if course_name.startswith('实践课程：'):
                                course_name = course_name[5:]
                            elif course_name.startswith('其他课程：'):
                                course_name = course_name[5:]
                            
                            print(f"  提取到 - 课程: {course_name}, 教师: {teacher_name}")
                            course_set.add((course_name, teacher_name, "24软件1班"))
                            all_teachers.add(teacher_name)
                            processed_rows += 1
                
                # 处理常规课程格式，如 "课程名称/.../教师姓名/..."
                elif '/' in cell_str and len(cell_str) > 10:
                    # 尝试从格式中提取课程和教师
                    parts = cell_str.split('/')
                    if len(parts) >= 4:
                        # 课程名称通常在第一个部分
                        course_name = parts[0].strip()
                        # 教师姓名通常在倒数第二个部分（在人数之前）
                        # 查找包含汉字的部分作为教师姓名
                        teacher_name = None
                        for i in range(len(parts)-2, 0, -1):  # 从倒数第二部分往前找
                            part = parts[i].strip()
                            if re.search(r'[\u4e00-\u9fa5]', part):  # 包含汉字
                                # 判断是否是教师姓名（2-4个汉字）
                                chinese_chars = re.findall(r'[\u4e00-\u9fa5]', part)
                                if 2 <= len(chinese_chars) <= 4:
                                    teacher_name = ''.join(chinese_chars)
                                    break
                        
                        # 如果找到了有效的课程名称和教师姓名
                        if course_name and teacher_name and len(course_name) > 2:
                            # 过滤掉不是课程的内容
                            if not any(keyword in course_name for keyword in ['上午', '下午', '晚上', '节次', '星期']):
                                print(f"  提取到常规课程 - 课程: {course_name}, 教师: {teacher_name}")
                                course_set.add((course_name, teacher_name, "24软件1班"))
                                all_teachers.add(teacher_name)
                                processed_rows += 1
                
                # 处理单独的课程名称（没有明显的教师信息）
                elif len(cell_str) > 4 and re.match(r'^[\u4e00-\u9fa5\(\)（）]+$', cell_str):
                    # 检查是否像是课程名称
                    if any(keyword in cell_str for keyword in ['计算机', '程序设计', '英语', '数学', '体育', '政治', '思想', '理论']):
                        course_name = cell_str.strip()
                        # 对于体育与健康课程，设置教师为黎春生
                        if '体育与健康' in course_name:
                            teacher_name = '黎春生'
                            print(f"  提取到单独课程 - 课程: {course_name}, 教师: {teacher_name}")
                            course_set.add((course_name, teacher_name, "24软件1班"))
                            all_teachers.add(teacher_name)
                            processed_rows += 1
    
    print(f"总共提取了 {processed_rows} 条课程信息")
    print(f"找到 {len(all_teachers)} 位教师: {', '.join(sorted(all_teachers))}")

# 准确的教师-课程映射表（扩展版本，添加更多教师）
CORRECT_TEACHER_COURSE_MAP = {
    # 体育课程
    '体育与健康（一）': '黎春生',
    '体育与健康（二）': '黎春生',
    '体育与健康（三）': '黎春生',
    # 军事课程
    '军事理论': '张一兵',
    # 劳动教育课程
    '劳动教育': '张一兵',
    # 思想道德类课程
    '思想道德与法治（一）': '殷红梅',
    '思想道德与法治（二）': '殷红梅',
    '习近平新时代中国特色社会主义思想概论': '刘芳',
    '毛泽东思想和中国特色社会主义理论体系概论': '刘芳',
    '改革开放史': '刘卓',
    # 计算机相关课程
    'Python程序设计': '张良峰',
    'Javascript编程技术': '黄雪琴',
    '网页设计与制作': '黄雪琴',
    '面向对象程序设计': '靳向峰',
    '软件工程': '梁辰',
    '软件测试技术': '杨晓楠',
    '数据库技术及应用': '庞寅',
    'Linux操作系统基础': '庞寅',
    '程序设计基础': '郭鹏',
    '计算机应用技术': '单继周',
    # 英语相关课程
    '大学英语（一）': '庞新思',
    '大学英语（二）': '庞新思',
    '人工智能导论': '王忠',
    # 安全教育相关
    '大学生安全教育(一)': '代晓明',
    '大学生安全教育(二)': '赵通通',
    '国家安全教育': '王冰',
    # 心理健康相关
    '大学生心理健康教育': '符冬琴',
    # 就业指导相关
    '职业发展与就业指导': '吴淑亲',
    # 形势政策相关
    '形势与政策（一）': '黄丽娟',
    '形势与政策（二）': '凌征福',
    '形势与政策（三）': '姜艳文',
    # 创新创业相关
    '大学生创新创业基础': '李丹',
    # 其他课程
    '海南自由贸易港建设': '张乐',
    '中华文化选读': '陈元芳',
    '国家安全教育': '王冰',
    '美育': '李红',
    '暑期社会实践': '蔡守正'
}

# 生成课程列表
def normalize_course_name(course_name):
    """归一化课程名称，将不同学期或类型的同名课程合并"""
    # 处理体育与健康课程
    if '体育与健康' in course_name:
        if '(一)' in course_name or '（一）' in course_name:
            return '体育与健康（一）'
        elif '(二)' in course_name or '（二）' in course_name:
            return '体育与健康（二）'
        elif '(三)' in course_name or '（三）' in course_name:
            return '体育与健康（三）'
        return '体育与健康'
    # 处理思想道德与法治课程
    if '思想道德与法治' in course_name:
        if '(一)' in course_name or '（一）' in course_name:
            return '思想道德与法治（一）'
        elif '(二)' in course_name or '（二）' in course_name:
            return '思想道德与法治（二）'
        return '思想道德与法治'
    # 处理形势与政策课程
    if '形势与政策' in course_name:
        if '(一)' in course_name or '（一）' in course_name:
            return '形势与政策（一）'
        elif '(二)' in course_name or '（二）' in course_name:
            return '形势与政策（二）'
        elif '(三)' in course_name or '（三）' in course_name:
            return '形势与政策（三）'
        return '形势与政策'
    # 处理大学英语课程
    if '大学英语' in course_name:
        if '(一)' in course_name or '（一）' in course_name:
            return '大学英语（一）'
        elif '(二)' in course_name or '（二）' in course_name:
            return '大学英语（二）'
        return '大学英语'
    # 处理大学生安全教育课程
    if '大学生安全教育' in course_name:
        if '(一)' in course_name or '（一）' in course_name:
            return '大学生安全教育(一)'
        elif '(二)' in course_name or '（二）' in course_name:
            return '大学生安全教育(二)'
        return '大学生安全教育'
    # 其他课程归一化规则
    return course_name

def normalize_teacher_name(course_name, teacher_name):
    """归一化教师姓名，使用准确的教师-课程映射表"""
    # 首先尝试归一化课程名称
    normalized_course = normalize_course_name(course_name)
    
    # 检查是否在准确映射表中
    if normalized_course in CORRECT_TEACHER_COURSE_MAP:
        return CORRECT_TEACHER_COURSE_MAP[normalized_course]
    
    # 如果不在映射表中，检查课程是否包含某些关键词
    for course_pattern, correct_teacher in CORRECT_TEACHER_COURSE_MAP.items():
        if course_pattern in normalized_course or normalized_course in course_pattern:
            return correct_teacher
    
    # 对于未知教师，保留原始信息
    return teacher_name


def generate_course_list(course_set):
    """生成唯一课程列表，确保包含映射表中的所有课程"""
    unique_courses = set()
    # 添加实际导入的课程
    for course, teacher, class_name in course_set:
        normalized_course = normalize_course_name(course)
        unique_courses.add(normalized_course)
    
    # 添加映射表中的所有课程，确保不会遗漏
    for course_name in CORRECT_TEACHER_COURSE_MAP.keys():
        unique_courses.add(course_name)
    
    return sorted(list(unique_courses))

# 生成教师授课列表
def generate_teacher_course_map(course_set):
    """生成教师到课程的映射，确保包含映射表中的所有教师"""
    teacher_map = defaultdict(set)
    
    # 首先添加映射表中的所有课程-教师关系
    for course, teacher in CORRECT_TEACHER_COURSE_MAP.items():
        teacher_map[teacher].add(course)
    
    # 然后处理从Excel提取的课程信息
    for course, teacher, class_name in course_set:
        if teacher and teacher != "未知":
            normalized_course = normalize_course_name(course)
            # 确保全面使用归一化后的教师名称
            normalized_teacher = normalize_teacher_name(course, teacher)
            teacher_map[normalized_teacher].add(normalized_course)
    
    # 转换为排序的列表格式
    result = []
    for teacher in sorted(teacher_map.keys()):
        courses = sorted(list(teacher_map[teacher]))
        result.append((teacher, courses))
    
    print(f"映射表生成后共有 {len(teacher_map)} 位教师")
    return result

# 保存结果到文件
def save_results(course_list, teacher_map):
    """保存处理结果到文件"""
    # 保存课程列表
    course_file = os.path.join(OUTPUT_DIR, "课程列表.txt")
    with open(course_file, 'w', encoding='utf-8') as f:
        f.write("=== 汇总课程列表 ===\n")
        for i, course in enumerate(course_list, 1):
            f.write(f"{i}. {course}\n")
    print(f"课程列表已保存到: {course_file}")
    
    # 保存教师授课列表
    teacher_file = os.path.join(OUTPUT_DIR, "教师授课列表.txt")
    with open(teacher_file, 'w', encoding='utf-8') as f:
        f.write("=== 教师授课列表 ===\n")
        for teacher, courses in teacher_map:
            f.write(f"\n【{teacher}】\n")
            for course in courses:
                f.write(f"  - {course}\n")
    print(f"教师授课列表已保存到: {teacher_file}")
    
    # 同时输出到控制台
    print("\n=== 汇总课程列表 ===")
    for i, course in enumerate(course_list, 1):
        print(f"{i}. {course}")
    
    print("\n=== 教师授课列表 ===")
    for teacher, courses in teacher_map:
        print(f"\n【{teacher}】")
        for course in courses:
            print(f"  - {course}")

# 主函数
def main():
    print("开始处理课表数据...")
    
    # 获取所有课表文件
    schedule_files = get_schedule_files()
    print(f"找到 {len(schedule_files)} 个课表文件")
    for file in schedule_files:
        print(f"- {os.path.basename(file)}")
    
    # 存储所有课程信息的集合
    all_courses = set()
    
    # 处理每个文件
    for file_path in schedule_files:
        print(f"\n处理文件: {os.path.basename(file_path)}")
        df = read_excel_data(file_path)
        extract_course_info(df, all_courses)
    
    # 生成结果
    print(f"\n总共提取了 {len(all_courses)} 条课程记录")
    
    # 更新任务状态
    print("\n完成任务2：编写Python脚本读取Excel文件并提取数据")
    print("开始任务3：整理课程列表信息")
    
    course_list = generate_course_list(all_courses)
    print(f"汇总得到 {len(course_list)} 门唯一课程")
    
    print("\n完成任务3：整理课程列表信息")
    print("开始任务4：整理教师授课列表信息")
    
    teacher_map = generate_teacher_course_map(all_courses)
    print(f"汇总得到 {len(teacher_map)} 位教师的授课信息")
    
    print("\n完成任务4：整理教师授课列表信息")
    print("开始任务5-6：保存并展示处理结果")
    
    # 保存结果
    save_results(course_list, teacher_map)
    
    print("\n所有任务完成！")

if __name__ == "__main__":
    main()